package cn.wen.yaling.xo.service.impl;

import cn.wen.yaling.commons.constant.RedisConstants;
import cn.wen.yaling.commons.enums.HttpCode;
import cn.wen.yaling.commons.enums.ResourceStatus;
import cn.wen.yaling.commons.service.RedisService;
import cn.wen.yaling.commons.utils.*;
import cn.wen.yaling.commons.vo.*;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import cn.wen.yaling.xo.dao.ResourcesDao;
import cn.wen.yaling.commons.entity.ResourcesEntity;
import cn.wen.yaling.xo.service.ResourcesService;


@Service("resourcesService")
public class ResourcesServiceImpl extends ServiceImpl<ResourcesDao, ResourcesEntity> implements ResourcesService {

    @Autowired
    private ResourcesDao resourcesDao;

    @Autowired
    private RedisService redisService;

    @Autowired
    private RedisUtils redisUtils;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<ResourcesEntity> page = this.page(
                new Query<ResourcesEntity>().getPage(params),
                new QueryWrapper<ResourcesEntity>()
        );
        return new PageUtils(page);
    }

    @Override
    public List<ResourceVO> getAllResources() {
        List<ResourceVO> resourceVOList;
        // 1、先判断redis缓存中是否能命中缓存
        if (redisService.hasKey(RedisConstants.CACHE_RESOURCES_LIST)) {
            resourceVOList = redisUtils.getListCache(RedisConstants.CACHE_RESOURCES_LIST, ResourceVO.class);
        } else {
            // 2、缓存不命中则到db中获取
            resourceVOList = resourcesDao.getAllResources();
            // 3、将db中的缓存获取到
            redisUtils.setListCache(RedisConstants.CACHE_RESOURCES_LIST, resourceVOList);
        }
        return resourceVOList;
    }

    @Override
    public ResultEntity addResource(ResourceAddVO resourceAddVO) {
        ResourcesEntity resourcesEntity = new ResourcesEntity();
        BeanUtils.copyProperties(resourceAddVO, resourcesEntity);
        // 1、修改状态 设置为审核中
        resourcesEntity.setResourceStatus(ResourceStatus.UNDER_REVIEW.getStatus());
        resourcesEntity.setIsPublish(true);
        resourcesEntity.setSourceUserId(UserHolder.getUser().getUserId());
        resourcesEntity.setSourceNickname(UserHolder.getUser().getUsername());
        // 2、设置时间
        resourcesEntity.setCreateTime(new Date());
        resourcesEntity.setUpdateTime(new Date());
        // 3、添加到数据库
        int insert = resourcesDao.insert(resourcesEntity);
        if (insert <= 0) return ResultEntity.error(HttpCode.内部服务器错误.getCode(), "添加资源失败！");
        redisUtils.delResourceListCache();
        return ResultEntity.ok();
    }

    @Override
    public List<ResourceListVO> getResourceList() {
        List<ResourceListVO> resourceList;
        // 1、先判断redis缓存中是否能命中缓存
        if (redisService.hasKey(RedisConstants.CACHE_ADMIN_ALL_RESOURCE_LIST)) {
            resourceList = redisUtils.getListCache(RedisConstants.CACHE_ADMIN_ALL_RESOURCE_LIST, ResourceListVO.class);
        } else {
            // 2、缓存不命中则到db中获取
            QueryWrapper<ResourcesEntity> queryWrapper = new QueryWrapper<>();
            queryWrapper.ne("resource_status", ResourceStatus.DELETE.getStatus());
            List<ResourcesEntity> resourcesEntities = resourcesDao.selectList(queryWrapper);
            resourceList = resourcesEntities.stream().map((item) -> {
                ResourceListVO target = new ResourceListVO();
                BeanUtils.copyProperties(item, target);
                return target;
            }).collect(Collectors.toList());
            // 3、将db中的缓存获取到
            redisUtils.setListCache(RedisConstants.CACHE_ADMIN_ALL_RESOURCE_LIST, resourceList);
        }
        return resourceList;
    }

    @Override
    public List<ResourceListVO> searchResource(String resourceName) {
        QueryWrapper<ResourcesEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.ne("resource_status", ResourceStatus.DELETE.getStatus());
        queryWrapper.like("source_name", resourceName);
        List<ResourcesEntity> resourcesEntities = resourcesDao.selectList(queryWrapper);
        return resourcesEntities.stream().map((item) -> {
            ResourceListVO target = new ResourceListVO();
            BeanUtils.copyProperties(item, target);
            return target;
        }).collect(Collectors.toList());
    }

    @Override
    public ResultEntity updateResource(ResourceUpdateVO resourceUpdateVO) {
        ResourcesEntity target = new ResourcesEntity();
        BeanUtils.copyProperties(resourceUpdateVO, target);
        target.setUpdateTime(new Date());
        if (target.getIsPublish()) {
            target.setResourceStatus(target.getIsPublish() ? ResourceStatus.PUBLISHED.getStatus() :
                    ResourceStatus.UNDER_REVIEW.getStatus());
        }
        boolean res = resourcesDao.updateById(target) > 0;
        if (!res) return ResultEntity.error();
        redisUtils.delResourceListCache();
        return ResultEntity.ok();
    }

    @Override
    public ResultEntity deleteByIds(Integer[] resourceIds) {
        boolean res = resourcesDao.updateByIds(resourceIds, ResourceStatus.DELETE.getStatus());
        if (!res) return ResultEntity.error(HttpCode.内部服务器错误.getCode(), "删除失败！");
        redisUtils.delQuestionListCache();
        return ResultEntity.ok();
    }

    @Override
    public ResultEntity updateResourceStatus(Integer resourceId, Integer status) {
        ResourcesEntity target = new ResourcesEntity();
        target.setResourceId(resourceId);
        target.setResourceStatus(status);
        boolean res = resourcesDao.updateById(target) > 0;
        if (!res) return ResultEntity.error();
        redisUtils.delResourceListCache();
        return ResultEntity.ok();
    }

    @Override
    public ResultEntity getAllSortList() {
        List<String> firstSortList;
        List<String> secondSortList;
        // 1、先判断redis缓存中是否能命中缓存
        if (redisService.hasKey(RedisConstants.CACHE_ADMIN_RESOURCE_FIRST_TYPE_LIST) &&
                redisService.hasKey(RedisConstants.CACHE_ADMIN_RESOURCE_SECOND_TYPE_LIST)) {
            firstSortList = redisUtils.getListCache(RedisConstants.CACHE_ADMIN_RESOURCE_FIRST_TYPE_LIST, String.class);
            secondSortList = redisUtils.getListCache(RedisConstants.CACHE_ADMIN_RESOURCE_SECOND_TYPE_LIST, String.class);
        } else {
            // 2、缓存不命中则到db中获取
            QueryWrapper<ResourcesEntity> queryWrapper = new QueryWrapper<>();
            queryWrapper.select("DISTINCT first_sort")
                    .eq("resource_status", ResourceStatus.PUBLISHED.getStatus());
            List<Object> objects = resourcesDao.selectObjs(queryWrapper);
            if (objects == null) return ResultEntity.error();
            firstSortList = objects.stream().map((item) -> {
                return (String) item;
            }).collect(Collectors.toList());
            QueryWrapper<ResourcesEntity> queryWrapper2 = new QueryWrapper<>();
            queryWrapper2.select("DISTINCT second_sort")
                    .eq("resource_status", ResourceStatus.PUBLISHED.getStatus());
            List<Object> objects2 = resourcesDao.selectObjs(queryWrapper2);
            if (objects2 == null) return ResultEntity.error();
            secondSortList = objects2.stream().map((item) -> {
                return (String) item;
            }).collect(Collectors.toList());
            // 3、将db中的缓存获取到
            redisUtils.setListCache(RedisConstants.CACHE_ADMIN_RESOURCE_FIRST_TYPE_LIST, firstSortList);
            redisUtils.setListCache(RedisConstants.CACHE_ADMIN_RESOURCE_SECOND_TYPE_LIST, secondSortList);
        }
        return ResultEntity.ok().put("secondSortList", secondSortList)
                .put("firstSortList", firstSortList);
    }

}